package PlotIntensitiesAndTime;

import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.measure.*;
import ij.plugin.filter.Analyzer;
import ij.plugin.filter.PlugInFilter;
import ij.util.Tools;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/** Implements the Image/Stack/Plot Z-axis Profile command. */
public class PlotIntensitiesAndTime implements PlugInFilter, Measurements, MouseListener {

	ImagePlus imp;
	ImageCanvas canvas;
	Plot plot;
	PlotWindow win;
	
	ij.Prefs prefs = new ij.Prefs(); 
	
	int trans_x;
	int trans_y;
	
	public int setup(String arg, ImagePlus imp) {
		this.imp = imp;
		if (!showDialog()){
			return DONE;
		}
		return DOES_ALL+NO_CHANGES;
	}
	
	/** Displays a modal options dialog. */
	private boolean showDialog() {
		GenericDialog gd = new GenericDialog("Plot Intensities");
		gd.addNumericField("pixel of x translation",
				prefs.get("PlotIntensitiesAndTime.trans_x", 0), 0);
		gd.addNumericField("pixel of y translation",
				prefs.get("PlotIntensitiesAndTime.trans_y", 0), 0);
		gd.addMessage("\n\nInput xy values for parallel shift");
		gd.showDialog();
		if (gd.wasCanceled()){
			return false;
		}
		//By using prefs.set(key, value), get and save values in edit/text boxes
		trans_x = (int)gd.getNextNumber();
		prefs.set("PlotIntensitiesAndTime.trans_x", trans_x);
		trans_y = (int)gd.getNextNumber();
		prefs.set("PlotIntensitiesAndTime.trans_y", trans_y);
		
		return true;
	}

	public void run(ImageProcessor ip) {
		if (imp.getStackSize()<2) {
			IJ.error("ZAxisProfiler", "This command requires a stack.");
			return;
		}
		Roi roi = imp.getRoi();
		if (roi == null){
			IJ.error("PlotIntensitiesAndTime", "Please set roi!");
			return;	
		}
		if (roi!=null && roi.isLine()) {
			IJ.error("ZAxisProfiler", "This command does not work with line selections.");
			return;
		}
		Rectangle r = roi.getBounds();
		Roi roi_back = new Roi(r.x, r.y + 10, r.width, r.height);
		Roi roi_para = new Roi(r.x + trans_x, r.y + trans_y, r.width, r.height);
		Roi roi_para_back = new Roi(r.x + trans_x, r.y + trans_y + 10, r.width, r.height);
		
		double minThreshold = ip.getMinThreshold();
		double maxThreshold = ip.getMaxThreshold();
		float[] y = getZAxisProfile(roi, minThreshold, maxThreshold);
		float[] y_back = getZAxisProfile(roi_back, minThreshold, maxThreshold);
		float[] y_para = getZAxisProfile(roi_para, minThreshold, maxThreshold);
		float[] y_para_back = getZAxisProfile(roi_para_back, minThreshold, maxThreshold);
		
		for(int i = 0; i < imp.getStackSize(); i++){
			y[i] -= y_back[i];
			y_para[i] -= y_para_back[i];
		}
		if (y!=null) {
			float[] x = new float[y.length];
			for (int i=0; i<x.length; i++)
				x[i] = i+1;
			String title;
			title = imp.getTitle()+"-"+r.x+"-"+r.y;
			plot = new Plot(title, "Slice", "Mean", x, y);
			plot.addPoints(x, y_para, Plot.LINE);
			plot.setColor(java.awt.Color.GREEN);
			double ymin = ProfilePlot.getFixedMin();
			double ymax= ProfilePlot.getFixedMax();
			if (!(ymin==0.0 && ymax==0.0)) {
				double[] a = Tools.getMinMax(x);
				double xmin=a[0]; double xmax=a[1];
				plot.setLimits(xmin, xmax, ymin, ymax);
			}
			win = plot.show();
		
			canvas = win.getCanvas();
			canvas.addMouseListener(this);
		}			
	}
		
	float[] getZAxisProfile(Roi roi, double minThreshold, double maxThreshold) {
		ImageStack stack = imp.getStack();
		int size = stack.getSize();
		float[] values = new float[size];
		Calibration cal = imp.getCalibration();
		Analyzer analyzer = new Analyzer(imp);
		int measurements = analyzer.getMeasurements();
		boolean showResults = measurements!=0 && measurements!=LIMIT;
		boolean showingLabels = (measurements&LABELS)!=0 || (measurements&SLICE)!=0;
		measurements |= MEAN;
		if (showResults) {
			if (!analyzer.resetCounter())
				return null;
		}
		int current = imp.getCurrentSlice();
		for (int i=1; i<=size; i++) {
			if (showingLabels) imp.setSlice(i);
			ImageProcessor ip = stack.getProcessor(i);
			if (minThreshold!=ImageProcessor.NO_THRESHOLD)
				ip.setThreshold(minThreshold,maxThreshold,ImageProcessor.NO_LUT_UPDATE);
			ip.setRoi(roi);
			ImageStatistics stats = ImageStatistics.getStatistics(ip, measurements, cal);
			analyzer.saveResults(stats, roi);
			if (showResults)			
				analyzer.displayResults();
			values[i-1] = (float)stats.mean;
		}
		if (showingLabels) imp.setSlice(current);
		return values;
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		int x = e.getX();
		int y = e.getY();
		int offscreenX = canvas.offScreenX(x);
		int offscreenY = canvas.offScreenY(y);
		IJ.log("mousePressed: " + offscreenX + "," + offscreenY);
//		double xv = (x-Plot.LEFT_MARGIN)/xScale + xMin;
//		double yv = (TOP_MARGIN+frameHeight-y)/yScale +yMin;
//		plot.drawLine(x, 0, x, win.plotHeight);
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	
}

